﻿using System;
using AdminSecurity.Extensions;
using Identity.AdminSecurityExtensions;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;

namespace Microsoft.AspNetCore.Authorization;
 
//
// 摘要:
//     授权扩展操作类
public static class AuthorizationPolicyBuilderExtensions
{
    //
    // 摘要:
    //     注入认证服务方法
    //
    // 参数:
    //   services:
    //
    //   optionsConfigure:
    //
    //   cookieConfigure:
    public static IServiceCollection AddAdminSecurity<TBootstrapAdminService>(
        this IServiceCollection services,
        IConfiguration configuration,
        Action<CookieAuthenticationOptions>? cookieConfigure = null)
        where TBootstrapAdminService : ISecutityAdminService
    {
        services.Configure<AdminAuthenticationOptions>(configuration.GetSection("AdminAuthentication"));
        services.AddScoped<AuthenticationStateProvider, AppAuthenticationStateProvider>();
        services.AddScoped(typeof(ISecutityAdminService), typeof(TBootstrapAdminService));

        var adminOptions = services.BuildServiceProvider().GetRequiredService<IOptions<AdminAuthenticationOptions>>().Value;
        services.AddCookieAuthentication(adminOptions, cookieConfigure);
        services.AddSingleton<IAuthorizationPolicyProvider, CustomAuthorizationPolicyProvider>();
        services.AddAuthorizationCore(options =>
        {
            options.DefaultPolicy = new AuthorizationPolicyBuilder()
                .RequireBootstrapAdminAuthorizate(services)
                .Build();
        });

        return services;
    }

    //
    // 摘要:
    //     RequireBootstrapAdminAuthorizate 扩展方法
    //
    // 参数:
    //   builder:
    //     AuthorizationPolicyBuilder 实例
    //
    //   services:
    private static AuthorizationPolicyBuilder RequireBootstrapAdminAuthorizate(this AuthorizationPolicyBuilder builder, IServiceCollection services)
    {
        builder.RequireAuthenticatedUser();

        // 使用服务提供程序动态解析依赖项
        // var serviceProvider = services.BuildServiceProvider();
        // builder.AddRequirements(new UserNavigationRequirement(serviceProvider));

        return builder;
    }
 

    private static AuthenticationBuilder AddCookieAuthentication(
        this IServiceCollection services,
        AdminAuthenticationOptions options,
        Action<CookieAuthenticationOptions>? cookieConfigure = null)
    {
        services.AddDataProtection(opts =>
        {
            opts.ApplicationDiscriminator = options.ApplicationDiscriminator;
        }).SetApplicationName(options.ApplicationAppName);

        return services.AddAuthentication("Cookies").AddCookie(opts =>
        {
            if (!string.IsNullOrEmpty(options.CookiePath))
            {
                opts.Cookie.Path = options.CookiePath;
            }

            if (!string.IsNullOrEmpty(options.CookieDomain))
            {
                opts.Cookie.Domain = options.CookieDomain;
            }

            cookieConfigure?.Invoke(opts);
        });
    }

    private static AuthenticationBuilder AddDomainAuthentication(this IServiceCollection services)
    {
        return services.AddAuthentication("Negotiate");
    }
}